// 首先看for...of
// =============Array==========
console.log('============Array===========');
for (const item of [1, 2, 3]) {
  console.log(item);
}

// ============Set============
console.log('============Set===========');
const s = new Set([1, 2, 3]);

for (const item of s) {
  console.log(item);
}

// ============Map===========
console.log('============Map===========');
const m = new Map();
m.set('name', 'cuvee');
m.set('age', 30);

for (const [key, value] of m) {
  console.log(key, value);
}

// 通过打开控制台可以看到arr、s、m的原型链上面都存在一个方法，方法名是[Symbol.iterator]，而通过调用[Symbol.iterator]
// 会返回一个带有next方法的对象，在next对象中会返回一个{ value: string, done: boolean }类型的对象。以上我们称
// 带有[Symbol.iterator]的对象称为Iteratorable，返回的带有next方法的对象称为Iterator，{ value: string, done: boolean }称为
// IterationResult

// 迭代器
const obj = {
  [Symbol.iterator]: function () {
    return {
      next: () => {
        return {
          value: 'cuvee',
          done: true,
        };
      },
    };
  },
};

for (const item of obj) {
  // 这儿不会报错，但是也不会打印；说明两个点：
  // 1、obj是Iteratorable
  // 2、第一次迭代的时候，指针的状态为true，立马结束了迭代
  console.log(item);
}
console.log('===============迭代器模式实例=============');
// todo.js
const todos = {
  life: ['LOL', 'Music'],
  work: ['Front-end engineer'],
  skills: ['JavaScript', 'Python'],
  each: function (cb) {
    const all = [...this.life, ...this.work, ...this.skills];
    for (const item of all) {
      cb && cb(item);
    }
  },
  [Symbol.iterator]: function () {
    const all = [...this.life, ...this.work, ...this.skills];
    let index = 0;
    return {
      next: () => {
        const result = {
          value: all[index],
          done: index >= all.length,
        };
        index++;
        return result;
      },
    };
  },
};

// display.js

for (const item of todos.life) {
  console.log(item);
}
for (const item of todos.work) {
  console.log(item);
}
for (const item of todos.skills) {
  console.log(item);
}
console.log('===========each===========');
todos.each(item => {
  console.log(item);
});

console.log('==========iterator========');

for (const item of todos) {
  console.log(item);
}
